/*
 * Created by Jaren at 2022/01/29 16:53
 */
import 'dart:typed_data';

import 'package:ble_plugin/ble_plugin.dart';
import 'package:get/get.dart';
import 'package:jieli_ble_ota_plugin/jieli_ble_ota_plugin.dart';
import 'package:jieli_ble_ota_plugin_example/base/base.dart';
import 'package:jieli_ble_ota_plugin_example/global/global.dart';
import 'package:jieli_ble_ota_plugin_example/widget/prompt.dart';

class FwUpdateController extends BaseController {
  late JieliBleOtaPlugin otaPlugin;

  late OtaCallback _otaCallback;
  late BleHandler _bleHandler;

  late String deviceIdentifier, deviceName;

  @override
  void init() async {
    _bleHandler = BleHandler(this);
    _otaCallback = BleOtaCallback(this);

    otaPlugin = JieliBleOtaPlugin(_bleHandler, _otaCallback, _bleHandler);

    BleManager().onNotifiedCallback = (device, values) async {
      otaPlugin.notifyDataReceived(Uint8List.fromList(values));
    };

    deviceName = BleManager().activeDevices.values.first.device.name;
    deviceIdentifier = BleManager().activeDevices.values.first.device.id.id;

    _bleHandler.bleName = deviceName;

    notifySDKConnected(deviceIdentifier, deviceName);

    await Future.delayed(const Duration(milliseconds: 1500));

    otaPlugin.requestDeviceFirmwareState();
  }

  void startUpdate() {
    otaPlugin.start("");
    btnText.value = "In Progress...";
    Global.getInstance().put("fw_updating", true);
    Global.getInstance().put("bt_state_change_handler", (connected, name) {
      if (connected) {
        updateStatus.value = "蓝牙已重连";
        notifySDKConnected(deviceIdentifier, deviceName);
      } else {
        updateStatus.value = "蓝牙已断开";
        notifySDKDisconnected(deviceIdentifier, deviceName);
      }
    });
  }

  void notifySDKConnected(String identifier, String name) {
    otaPlugin.notifyLinkConnected(identifier, name);
  }

  void notifySDKDisconnected(String identifier, String name) {
    otaPlugin.notifyLinkDisconnected(identifier, name);
  }

  void cancelUpdate() {}

  void showMessage(String msg) {
    Prompt.showMessageDialog(msg);
  }

  void release() {
    Global.getInstance().remove("fw_updating");
    Global.getInstance().remove("bt_state_change_handler");
  }

  RxString updateStatus = "就绪".obs;
  RxString btnText = "开始".obs;
}

class BleHandler extends DataWriteHandler with LinkLayerHandler {
  FwUpdateController _controller;

  String? bleName;

  BleHandler(this._controller);

  @override
  Future writeBytes(Uint8List bytes) async {
    return await BleManager().write(bytes);
  }

  @override
  Future disconnect() {
    return BleManager().disconnect();
  }

  @override
  Future reconnect([bool shouldNotifySDKWhenConnected = true, bool shouldNotifySDKWhenDisconnected = true, Function? connectCallback]) {
    return Future(() => BleManager().connect(name: bleName));
  }
}

class BleOtaCallback extends OtaCallback {
  FwUpdateController _controller;

  BleOtaCallback(this._controller);

  @override
  void onDeviceFirmwareStatusRequested(bool success, bool isFirmwareBroken) {
    print("onDeviceFirmwareStatusRequested, success: $success, isFirmwareBroken: $isFirmwareBroken");

    _controller.updateStatus.value = "设备状态信息${success ? '：${isFirmwareBroken ? '需要强制升级' : '无需强制升级'}' : '获取失败'}";
  }

  @override
  void onOtaProgressChanged(int state, double progress) {
    print("onOtaProgressChanged, state: $state, progress: $progress");

    _controller.updateStatus.value = "${state == 0 ? '正在下载 Bootloader' : '正在升级'}, ${progress.toStringAsFixed(2)}%";
  }

  @override
  void onOtaUpdateFailed(String code) {
    _controller.updateStatus.value = "升级失败";
    _controller.btnText.value = "开始";
    _controller.showMessage("升级失败，错误码：$code");
  }

  @override
  void onOtaUpdateSuccess() {
    _controller.updateStatus.value = "蓝牙已断开";
    _controller.btnText.value = "开始";
    _controller.showMessage("升级成功!");
  }
}
